package filter

import (
	"bytes"
	"github.com/emicklei/go-restful/v3"
	"github.com/rs/zerolog/log"
	"io/ioutil"
	"net/http"
	"time"
	recordRepo "webGoDemo/dao/record"
	"webGoDemo/model"
)

func BodyLogFilter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {

	inBody, err := ioutil.ReadAll(req.Request.Body)
	doc := req.SelectedRoute().Doc()
	if err != nil {
		_ = resp.WriteError(400, err)
		return
	}
	req.Request.Body = ioutil.NopCloser(bytes.NewReader(inBody))

	c := NewResponseCapture(resp.ResponseWriter)
	resp.ResponseWriter = c

	//// 允许跨域
	//if origin := req.Request.Header.Get("Origin"); origin != "" {
	//	resp.AddHeader("Access-Control-Allow-Origin", origin)
	//}

	chain.ProcessFilter(req, resp)

	// 获取当前请求的的url 以及method
	log.Info().Str("url", req.Request.URL.String()).
		Str("method", req.Request.Method).
		Str("request", string(inBody)).
		Int("code", resp.StatusCode()).
		Str("response", string(c.Bytes())).
		Str("doc", doc).
		Msg("http handled")



	// 创建一个record 对象 包进去。
	record := &model.Record{
		Url:            req.Request.URL.String(),
		MethodType:     req.Request.Method,
		Operator:       "admin",
		StartTime:      time.Now().Unix() * 60,
		ReturnCode:     resp.StatusCode(),
		Message:        "接口返回的message",
		OperateContent: doc,
	}

	log.Info().Interface("record", record).Send()
	//插入到数据库中
	repo := recordRepo.NewDaoService()
	err = repo.Insert(record)
	if err != nil {
		panic("插入有问题")
	}

}

type ResponseCapture struct {
	http.ResponseWriter
	wroteHeader bool
	status      int
	body        *bytes.Buffer
}

func NewResponseCapture(w http.ResponseWriter) *ResponseCapture {
	return &ResponseCapture{
		ResponseWriter: w,
		wroteHeader:    false,
		body:           new(bytes.Buffer),
	}
}

func (c ResponseCapture) Header() http.Header {
	return c.ResponseWriter.Header()
}

func (c ResponseCapture) Write(data []byte) (int, error) {
	if !c.wroteHeader {
		c.WriteHeader(http.StatusOK)
	}
	c.body.Write(data)
	return c.ResponseWriter.Write(data)
}

func (c *ResponseCapture) WriteHeader(statusCode int) {
	c.status = statusCode
	c.wroteHeader = true
	c.ResponseWriter.WriteHeader(statusCode)
}

func (c ResponseCapture) Bytes() []byte {
	return c.body.Bytes()
}

func (c ResponseCapture) StatusCode() int {
	return c.status
}
